package integerTree;

import java.util.LinkedList;
import java.util.Queue;

public class Tree {
    private Node treeRoot;

    public Tree(int rootNodeValue) {
        treeRoot = new Node(rootNodeValue);
    }

    private void insert(Node node, int value) {
        if (value < node.getNodeValue()) {
            if (node.getLeftChild() != null) {
                insert(node.getLeftChild(), value);
            } else {
                System.out.println("Inserted #" + value + " as left child of node #" + node.getNodeValue());
                node.setLeftChild(new Node(value));
            }
        } else if (value > node.getNodeValue()) {
            if (node.getRightChild() != null) {
                insert(node.getRightChild(), value);
            } else {
                System.out.println("Inserted #" + value + " as right child of node #" + node.getNodeValue());
                node.setRightChild(new Node(value));
            }
        }
    }

    private boolean remove(Node treeRoot, int value) {
        if (treeRoot != null) {
            if (treeRoot.getNodeValue() == value) {
                Node tempRoot = new Node(0);
                tempRoot.setLeftChild(treeRoot);
                return treeRoot.remove(tempRoot, value);
            } else {
                return treeRoot.remove(null, value);
            }
        } else return false;
    }

    private void printInDepthOrder(Node node) {
        if (node != null) {
            System.out.println("Traversed in depth node #" + node.getNodeValue());
            printInDepthOrder(node.getLeftChild());
            printInDepthOrder(node.getRightChild());
        }
    }

    private void printBreadthOrder(Node rootNode) {
        Queue<Node> breadthQueue = new LinkedList<Node>();
        if (rootNode != null) {
            breadthQueue.clear();
            breadthQueue.add(rootNode);
            while (!breadthQueue.isEmpty()) {
                Node node = breadthQueue.remove();
                System.out.print(node.getNodeValue() + " ");
                if (node.getLeftChild() != null) breadthQueue.add(node.getLeftChild());
                if (node.getRightChild() != null) breadthQueue.add(node.getRightChild());
            }
        }
    }

    public void insertNode(int value) {
        insert(treeRoot, value);
    }

    public boolean removeNode(int value) {
        return remove(treeRoot, value);
    }

    public void printInDepthOrder() {
        printInDepthOrder(treeRoot);
    }

    public void printBreadthOrder() {
        printBreadthOrder(treeRoot);
    }
}
